//@author A0081058H
package net.mysoc.w111j.ui.validation;

import static net.mysoc.w111j.ui.Constants.DATE_FORMAT;

import java.util.Calendar;
import java.util.Date;

import javafx.scene.control.Label;
import javafx.scene.image.ImageView;
import javafx.util.converter.DateStringConverter;
import net.mysoc.w111j.model.Money;

/**
 * Contains validation methods and utility formatting validation methods.
 */
public class Validation {
    /**
     * Formats a label to display a validation message.
     *
     * @param message the {@code ValidationMessage} containing validation information.
     * @param label the {@code Label} to be formatted.
     */
    public static void formatValidationLabel(ValidationMessage message, Label label) {
        switch (message.getState()) {
        case OK:
            label.setText("");
            label.setGraphic(new ImageView("checkaltg16.png"));
            label.getStyleClass().addAll("validation-ok");
            label.getStyleClass().removeAll("validation-error", "validation-warning");
            break;
        case WARNING:
            label.setText(message.getMessage());
            label.setGraphic(new ImageView("infoo16.png"));
            label.getStyleClass().removeAll("validation-ok", "validation-error");
            label.getStyleClass().addAll("validation-warning");
            break;
        case ERROR:
            label.setText(message.getMessage());
            label.setGraphic(new ImageView("arrowleftaltr16.png"));
            label.getStyleClass().removeAll("validation-ok", "validation-warning");
            label.getStyleClass().addAll("validation-error");
            break;
        }
    }

    /**
     * Validates by checking for empty text.
     *
     * @param name the {@code String} to validate as a name.
     * @return a {@code ValidationMessage} representing validation state.
     */
    public static ValidationMessage validateRequired(String name) {
        if (name == null || name.isEmpty()) {
            return new ValidationMessage(ValidationState.ERROR, "Required");
        }

        return new ValidationMessage();
    }

    /**
     * Validates a {@code String}, checking if is is a valid {@code Money} representation.
     *
     * @param price the {@code String} to validate as a {@code Money}.
     * @return a {@code ValidationMessage} representing validation state.
     */
    public static ValidationMessage validateMoney(String money) {
        if (money == null || money.isEmpty()) {
            return new ValidationMessage(ValidationState.ERROR, "Required");
        } else {
            try {
                new Money(money);
            } catch (Exception e) {
                return new ValidationMessage(ValidationState.ERROR, "Invalid");
            }
        }

        return new ValidationMessage();
    }

    /**
     * Validates date {@code String}s. Checks for invalid and future dates.
     *
     * @param dateString the {@code String} to validate as a date.
     * @return a {@code ValidationMessage} representing validation state.
     */
    public static ValidationMessage validateDate(String dateString) {
        if (dateString == null || dateString.isEmpty()) {
            return new ValidationMessage(ValidationState.ERROR, "Required");
        }

        try {
            Date date = new DateStringConverter(DATE_FORMAT).fromString(dateString);
            if (date.after(Calendar.getInstance().getTime())) {
                // Date is in the future, warn user
                return new ValidationMessage(ValidationState.WARNING, "Future date");
            }
        } catch (Exception e) {
            return new ValidationMessage(ValidationState.ERROR, "Invalid");
        }

        return new ValidationMessage();
    }
}
